import hashlib
import json
import os
import re
import sys
import time

import aiohttp as aiohttp
import jsonpath
import requests
from PyQt5 import uic
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget, QApplication, QDesktopWidget, QLineEdit, QPushButton, QHBoxLayout, QVBoxLayout, \
    QLabel, QSpinBox, QTableWidget, QHeaderView, QTableWidgetItem
from PyQt5.uic.properties import QtWidgets


class DownloadThread(QThread):
    signal = pyqtSignal(str)

    def __init__(self):
        super(DownloadThread, self).__init__()
        # self.show_translate = show_translate
        self.url = ''
        self.pages = None
        self.headers = {
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36",
            "cookie": "_xmLog=h5&3abef489-b7c1-4015-9594-2fa41e9a072d&2.1.2; x_xmly_traffic=utm_source%253A%2526utm_medium%253A%2526utm_campaign%253A%2526utm_content%253A%2526utm_term%253A%2526utm_from%253A"
        }

    def run(self):
        # headers = {
        #     "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36",
        #     "cookie": "_xmLog=h5&3abef489-b7c1-4015-9594-2fa41e9a072d&2.1.2; x_xmly_traffic=utm_source%253A%2526utm_medium%253A%2526utm_campaign%253A%2526utm_content%253A%2526utm_term%253A%2526utm_from%253A"
        # }

        download_url = self.url
        if not download_url:
            return
        # url_text = json.loads(text)
        # url = url_text.get('url')
        # pages = url_text.get('pages')
        r1 = requests.get(download_url, headers=self.headers)
        r1.encoding = 'utf-8'
        # print(r1.text)
        ret = re.search(r'<head><title>(.*?M)', r1.text)
        name = ret.group(1)

        # url = 'https://www.ximalaya.com/yinyue/291718/'
        nums = re.search(r'([\d]+)', download_url)
        num = nums.group(1)
        print(num)
        xmly_names = []
        xmly_list = []
        for page in range(1, int(self.pages) + 1):
            url2 = 'https://www.ximalaya.com/revision/album/v1/getTracksList?albumId=%s&pageNum=%s' % (num, page)
            r = requests.get(url2, headers=self.headers)
            content = json.loads(r.content)

            xmly_url_lists = jsonpath.jsonpath(content, '$..tracks')[0]
            for xmly_url_list in xmly_url_lists:
                xmly_name = xmly_url_list['title']
                u = xmly_url_list['trackId']
                xmly_names.append(xmly_name)
                xmly_list.append(u)

        print(xmly_names)
        print(xmly_list)
        # print(xmly_names[0])
        # ret = re.search(r"(.*?》)", xmly_names[0])
        # name = ret.group(1)
        if not os.path.exists('./%s' % name):
            os.mkdir('./%s' % name)
        # print(name)
        i = 0
        for xmly in xmly_list:
            download_url = 'https://www.ximalaya.com/revision/play/v1/audio?id=%s&ptype=1' % xmly
            r2 = requests.get(download_url, headers=self.headers)
            r2.encoding = 'utf-8'
            xmly_html = r2.text
            xmly_html = json.loads(xmly_html)
            xmly_urls = jsonpath.jsonpath(xmly_html, '$..data')[0]
            xmly_u = xmly_urls['src']
            print(xmly_u)

            r3 = requests.get(xmly_u, headers=self.headers, stream=True)
            # file_name = os.mkdir('./%s'% )
            with open('./%s/%s.mp3' % (name, xmly_names[i]), 'wb') as f:
                frequency_content_len = int(r3.headers.get('Content-Length', 1))
                write_content_len = 0
                # f.write(r3.content)
                print(frequency_content_len)

                show_download = {
                    'url_num': download_url,
                    'name': xmly_names[i],
                    'percent': '0%',
                    'path': name
                }
                last_time = time.time()
                while True:
                    try:
                        video_content = r3.iter_content(100)
                        for temp in video_content:
                            write_len = f.write(temp)
                            # print("正在写入视频文件, 字节大小为:", write_len)
                            write_content_len += write_len
                            percent = "%02.2f%%" % (100 * write_content_len / frequency_content_len)
                            # print(percent)
                            if time.time() - last_time >= 1:
                                last_time = time.time()
                                show_download['percent'] = percent
                                self.signal.emit(json.dumps(show_download))
                            if write_len < 100:
                                show_download['percent'] = "100%"
                                self.signal.emit(json.dumps(show_download))
                    except requests.exceptions.StreamConsumedError:
                        # print("写入文件成功...")
                        show_download['percent'] = "100%"
                        self.signal.emit(json.dumps(show_download))
                        break
                    i += 1
                self.signal.emit(json.dumps(show_download))


class ShowDownload(QWidget):
    def __init__(self):
        super(ShowDownload, self).__init__()
        self.__init_ui()

    def __init_ui(self):
        self.table = QTableWidget(0, 3)  # 4行3列
        self.table.setHorizontalHeaderLabels(['音频名称', '下载进度', '操作'])

        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Interactive)  # 第2列的宽度随内容自适应
        self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Interactive)  # 第3列的宽度随内容自适应

        # 设置垂直布局
        layout = QVBoxLayout()
        layout.addWidget(self.table)

        self.setLayout(layout)


class OpenFileBtn(QPushButton):
    def __init__(self, file_name, path, name="播放音频"):
        super().__init__(name)
        self.file_name = file_name
        self.path = path
        self.clicked.connect(self.open_file)

    def open_file(self):
        # print("点击了 打开文件 按钮")
        # Windows电脑打开视频方式
        print(self.file_name)
        print(self.path)
        print(os.getcwd())
        y_path = os.getcwd()

        # os.startfile(具体的文件路径 例如 c:/a/b/c/123.mp4)
        yp_path = y_path + '\\' + self.path + '\\' + self.file_name + '.mp3'
        print(yp_path)
        os.startfile(yp_path)

        # Mac电脑打开视频方式
        # subprocess.call(["open", os.path.join(os.path.expanduser('~')) + "/" + self.file_name])


class OpenFolder(QPushButton):
    def __init__(self, file_name, path, name="打开文件夹"):
        super().__init__(name)
        self.file_name = file_name
        self.path = path
        self.clicked.connect(self.open_file)

    def open_file(self):
        y_path = os.getcwd()
        start_directory = y_path + '/' + self.path
        os.startfile(start_directory)
        # # print("点击了 打开文件 按钮")
        # # Windows电脑打开视频方式
        # print(self.file_name)
        # print(self.path)
        # print(os.getcwd())
        # y_path = os.getcwd()
        #
        # # os.startfile(具体的文件路径 例如 c:/a/b/c/123.mp4)
        # yp_path = y_path + '\\' + self.path + '\\' + self.file_name + '.mp3'
        # print(yp_path)
        # os.startfile(yp_path)


class Folder(QWidget):
    def __init__(self):
        super().__init__()
        self.__init_ui()

    def __init_ui(self):
        self.table = QTableWidget(0, 2)  # 4行3列
        self.table.setHorizontalHeaderLabels(['文件夹名称', '操作'])

        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Interactive)  # 第2列的宽度随内容自适应
        # self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Interactive)  # 第3列的宽度随内容自适应
        layout = QVBoxLayout()
        layout.addWidget(self.table)

        self.setLayout(layout)


# UI主线程
class MyWindow(QWidget):
    db_signal = pyqtSignal(str)

    def __init__(self):
        super(MyWindow, self).__init__()
        self.init_ui()
        # 定义一些用到的属性
        self.histroy_dict = dict()

    def init_ui(self):
        self.resize(1052, 400)
        self.setWindowTitle('喜马拉雅')
        self.setWindowIcon(QIcon('龙.png'))
        screen = QDesktopWidget().screenGeometry()  # 获取屏幕坐标系
        size = self.geometry()  # 获取窗口坐标系
        left = (screen.width() - size.width()) / 2
        top = (screen.height() - size.height()) / 2
        self.move(left, top)
        c = QHBoxLayout()
        # 创建一个整体布局器
        container = QVBoxLayout()
        # 创建一个文本
        text1 = QLabel('请输入要下载的网址:')
        # 创建一个输入框
        self.url = QLineEdit()
        text2 = QLabel('请输入要下载的页数:')
        self.pages = QSpinBox()
        # 创建一个新的窗口显示下载详情
        self.show_download = ShowDownload()

        # 创建一个新的窗口显示文件夹
        self.folder = Folder()
        # 创建一个下载按钮
        start_download = QPushButton('开始下载')
        # 给按钮设置信号被触发后要调用的槽函数

        open_filder = QPushButton('打开文件夹')
        start_download.clicked.connect(self.download_url)

        # self.download_thread = DownloadThread()

        # self.download_thread.signal.connect(self.download_thread.download)
        v_layout1 = QHBoxLayout()
        v_layout2 = QHBoxLayout()
        v_layout3 = QVBoxLayout()
        v_layout1.addWidget(text1)
        v_layout1.addWidget(self.url)
        v_layout2.addWidget(text2)
        v_layout2.addWidget(self.pages)

        v_layout3.addWidget(self.folder)
        # v_layout3.addWidget(open_filder)

        container.addLayout(v_layout1)
        container.addLayout(v_layout2)
        container.addWidget(self.show_download)
        container.addWidget(start_download)
        c.addLayout(v_layout3)
        c.addLayout(container)

        # 开启线程
        # self.download_thread.start()
        self.setLayout(c)

    def download_url(self):
        url = self.url.text()
        pages = self.pages.text()
        self.download_thread = DownloadThread()
        self.download_thread.url = url
        self.download_thread.pages = pages
        self.download_thread.signal.connect(self.update_table_data)
        self.download_thread.start()
        # self.download_thread.signal.emit(json.dumps({'url': url, 'pages': pages}))
        # print(url)

    # def get_folder_row(self):

    def get_row_col(self, one_download_history):
        h = hashlib.md5()
        # print('111')
        h.update(one_download_history['url_num'].encode())
        hash_val = h.hexdigest()[:6]  # 只留6位即可
        # print(hash_val)
        histroy_info = self.histroy_dict.get(hash_val)
        if not histroy_info:
            row = len(self.histroy_dict.keys())
            one_download_history['id'] = row
            self.histroy_dict[hash_val] = one_download_history
            return row
        else:
            return histroy_info.get("id")

    def update_table_data(self, param):
        # print("槽函数被执行...", param)
        one_download_history = json.loads(param)
        print(one_download_history)
        folder_row = []
        if one_download_history['path'] not in folder_row:
            folder_row.append(one_download_history['path'])
        print(len(folder_row))
        row = self.get_row_col(one_download_history)
        # print(row)
        table_row_num = self.show_download.table.rowCount()
        folder_row_num = self.folder.table.rowCount()
        print(table_row_num)
        if row >= table_row_num:
            self.show_download.table.setRowCount(table_row_num + 1)
        self.show_download.table.setItem(row, 0, QTableWidgetItem(one_download_history['name']))
        self.show_download.table.setItem(row, 1, QTableWidgetItem(one_download_history['percent']))
        self.show_download.table.setCellWidget(row, 2,
                                               OpenFileBtn(one_download_history['name'], one_download_history['path']))

        if len(folder_row) - 1 >= folder_row_num:
            self.folder.table.setRowCount(table_row_num + 1)
        self.folder.table.setItem(len(folder_row) - 1, 0, QTableWidgetItem(one_download_history['path']))
        self.folder.table.setCellWidget(len(folder_row) - 1, 1,
                                        OpenFolder(one_download_history['name'], one_download_history['path']))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    app.exec()
